#!/usr/bin/perl -w # for syntax highlighting
package clreqd_modules;

#########################################################################
# This rountine checks for active applications on the local node and	#
# checks the sizes of the application_fs info and if different from	#
# the volume size will change it.					#
#									#
# Notice the size comparision is done at the lvm level not at the	#
# mount point level, since these can be different for drbd.		#
#########################################################################

use cldb;
use Sys::Hostname;
use daemon_connect;
use lvm;

sub lvm_fsinfo_sync {
my %ARGS=@_;
my $f;
# my $sql="SELECT * FROM application_fs WHERE name = 'master';";
my $conn;
my @R=();

	my $hostname=hostname();
	# We only work if the local status daemon is running
	my $stat_daemon=new daemon_connect(host => hostname, daemon => "statd", timeout => 3);
	if(!defined($stat_daemon)) {
		# no local status daemon
		return "ERROR No local status daemon.";
	}
	my $r=$stat_daemon->send_request(ONEWAY=>0, MSG=>"GET_APP_SUMMARY");
	if(!defined($r)) {
		return "ERROR No response from local status daemon.";
	}
	if($r !~ /^OK/) {
		return "ERROR $r";
	}
	my @A=();
	my @F=split(/\n/,$r);
	for my $cline (@F[1 .. $#F]) {
		my @F2=split(/\s+/,$cline);
		if($F2[2] eq "RUNNING" && $F2[1] eq $hostname) {
			push @A,$F2[0];
		}
	}

	return "OK" if @A==0;

	#################################################################
	# Now @A is a list of applications running locally ...		#
	# so get all application_fs details				#
	#################################################################

	my $LVM_STUFF=new lvm();
	if(!defined($LVM_STUFF)) {
		return "ERROR Unable to query LVM configuration.";
	}

	my $cldb=new cldb("$::ENV{TRUECL_CFG}/config.db");
	if(!defined($cldb)) {
		return "ERROR Unable to access the 'config' database.";
	}
	my @to_add=();
	my @to_delete=();
	my @to_modify=();
	for my $capp (@A) {
		# Get all application_fs records in database for app...
		my %app_vgs=();
		my $res=$cldb->get_rows("SELECT * FROM application_fs WHERE name = '$capp';");
		for my $cfs (@$res) {
			next if !defined($cfs->{name});
			my @lvinfo=$LVM_STUFF->get_lvinfo(VGNAME=>$cfs->{vg},LVNAME=>$cfs->{lv});
			# If the lv no longer exists then we should delete it.
			if(!defined($lvinfo[0])) {
				push @to_delete,[$capp,$cfs->{vg},$cfs->{lv}];
				next;
			}
			$app_vgs{$cfs->{vg}}=1;
			# Check the sizes and add to list if different..
			if($lvinfo[1] != $cfs->{size}) {
				push @to_modify,[$capp,$cfs->{vg},$cfs->{lv},$lvinfo[1]];
				next;
			}
		}
		for my $cvg (keys %app_vgs) {
			my @lvlist=$LVM_STUFF->lv_list(VGNAME=>$cvg);
			for my $clv (@lvlist) {
				my $f=0;
				for my $cfs (@$res) {
					next if !defined($cfs->{name});
					if($cfs->{lv} eq $clv) {
						$f=1; last;
					}
				}
				if(! $f) {
					my @lvinfo=$LVM_STUFF->get_lvinfo(VGNAME=>$cvg,LVNAME=>$clv);
					push @to_add,[$capp,$cvg,$clv,$lvinfo[1]];
				}
			}
		}
	}

	#################################################################
	# Return the recommended actions - though we do not do anything	#
	# since the higher level routine should take these and apply	#
	# across all nodes...						#
	#################################################################

	push @R,"OK";
	for my $c (@to_add) {
		push @R,"ADD: $c->[0] $c->[1] $c->[2] $c->[3]";
	}
	for my $c (@to_modify) {
		push @R,"MOD: $c->[0] $c->[1] $c->[2] $c->[3]";
	}
	for my $c (@to_delete) {
		push @R,"DEL: $c->[0] $c->[1] $c->[2]";
	}
	return join("\n",@R);
}

1;
